using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using Retrofit.Core;

namespace Retrofit
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class PlayerManager : Microsoft.Xna.Framework.GameComponent
    {
        public int CurrentPlayers { get; set; }
        public readonly int MaxPlayers;
        public List<PlayerIndex> Players { get; private set; }
        public event Action<PlayerIndex> PlayerJoinedGame;

        public PlayerManager(Game game)
            : base(game)
        {
            CurrentPlayers = 0;
            MaxPlayers = 4;
            Players = new List<PlayerIndex>(MaxPlayers);
        }

        public void OnPlayerJoined(PlayerIndex playerIndex)
        {
            if (PlayerJoinedGame != null)
            {
                PlayerJoinedGame(playerIndex);
            }
        }

        public PlayerIndex GetPlayer(int playerNumber)
        {
            if (playerNumber < 1 || playerNumber > 4)
            {
                throw new ArgumentException("Player Number must be from 1 to 4.");
            }

            try
            {
                PlayerIndex playerIndex = Players[ playerNumber - 1];
                return playerIndex;
            }
            catch (IndexOutOfRangeException ex)
            {
                Log.WriteLine(LogCategory.Exception, ex.Message);
                throw ex;
            } 
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            // TODO: Add your initialization code here

            base.Initialize();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            for (PlayerIndex it = PlayerIndex.One; it < PlayerIndex.Four; it++)
            {
                if ((CurrentPlayers >= MaxPlayers) || (Players.Contains(it)))
                {
                    break;
                }
                
            
                if (GamePad.GetState(it).IsButtonDown(Buttons.Start)
                    || GamePad.GetState(it).IsButtonDown(Buttons.A))
                {
                    Players.Add(it);
                    CurrentPlayers++;
                    OnPlayerJoined(it);
                }
            }

            base.Update(gameTime);
        }
    }
}